﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using UnityEditor;
using UnityEditor.Scripting;
using UnityEditor.Scripting.Compilers;
using UnityEditor.Utils;
using UnityEngine;

internal class PostProcessFlashPlayer
{
    private static FlashFileHelper _fileHelper;
    private static FlashPostProcessSettings _settings;

    private static void AppendUserAssembliesFormattedForCommandLine(StringBuilder cmdline)
    {
        IEnumerator<string> enumerator = _fileHelper.GetUserAssemblies().GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                string current = enumerator.Current;
                cmdline.Append(current);
                cmdline.Append(" ");
            }
        }
        finally
        {
            if (enumerator == null)
            {
            }
            enumerator.Dispose();
        }
    }

    private static void CleanWorkingPaths()
    {
        FileUtil.CreateOrCleanDirectory(_fileHelper.PathForConvertedDotNetCode());
        FileUtil.CreateOrCleanDirectory(_fileHelper.PathForAs3Src());
    }

    private static void CreateSerializedFileContainer()
    {
        _fileHelper.CopyResourcesFromPlayerPackageToStaging();
        SerializedFileContainerPreparer.CreateSerializedFileContainer(_fileHelper);
    }

    private static void DeleteAndCopyDefaultFiles()
    {
        FileUtil.DeleteFileOrDirectory(_fileHelper.PathForHtmlInInstallPath());
        FileUtil.DeleteFileOrDirectory(_fileHelper.PathForFileInInstallPath("swfobject.js"));
        FileUtil.DeleteFileOrDirectory(_fileHelper.PathForFileInInstallPath("embeddingapi.swc"));
        FileUtil.DeleteFileOrDirectory(_fileHelper.InstallPath);
        FileUtil.CopyFileOrDirectory(_fileHelper.PathForTempSwfUnprepared(), _fileHelper.InstallPath);
        FileUtil.CopyFileOrDirectory(_fileHelper.PathForFileInBuildTools("swfobject.js"), _fileHelper.PathForFileInInstallPath("swfobject.js"));
        FileUtil.CopyFileOrDirectory(_fileHelper.PathForFileInBuildTools("UnityShared.swc"), _fileHelper.PathForFileInInstallPath("embeddingapi.swc"));
    }

    private static void LogCompilerMessages(IEnumerable<CompilerMessage> messages)
    {
        IEnumerator<CompilerMessage> enumerator = messages.GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                CompilerMessage current = enumerator.Current;
                UnityEngine.Debug.LogPlayerBuildError(current.message, current.file, current.line, current.column);
            }
        }
        finally
        {
            if (enumerator == null)
            {
            }
            enumerator.Dispose();
        }
    }

    internal static void PostProcess(PostProcessFlashPlayerOptions options)
    {
        _settings = FlashPostProcessSettings.CreateFrom(options);
        _fileHelper = FlashFileHelper.CreateFrom(options);
        CleanWorkingPaths();
        if (ValidateAssemblies(options))
        {
            RunCil2As();
            CreateSerializedFileContainer();
            RunMxmlc();
            RunSwfPostProcessor();
            DeleteAndCopyDefaultFiles();
            WriteHtml();
            if (options.IsAutoRunPlayer)
            {
                Process.Start(_fileHelper.PathForHtmlInInstallPath());
            }
        }
    }

    private static void RunCil2As()
    {
        StringBuilder cmdline = new StringBuilder("-with-class-index -libid:ConvertedDotNetCode -with-global-package --baseclasslibraries-directory=");
        cmdline.Append(CommandLineFormatter.PrepareFileName(MonoInstallationFinder.GetProfileDirectory(BuildTarget.FlashPlayer, "unity")));
        cmdline.Append(" ");
        AppendUserAssembliesFormattedForCommandLine(cmdline);
        string str = _fileHelper.PathForConvertedDotNetCode();
        cmdline.Append(str);
        StartManagedProgram(cmdline.ToString(), new Cil2AsOutputParser(), _fileHelper.PathForCil2AsExe());
    }

    private static void RunMxmlc()
    {
        ProcessStartInfo si = new ProcessStartInfo {
            FileName = "java",
            Arguments = string.Join(" ", MxmlcHelper.MxmlcArgumentsFor(_settings, _fileHelper)),
            CreateNoWindow = true
        };
        StartProgramChecked(new Program(si), new FlexCompilerOutputParser(), "java");
    }

    private static bool RunSwfPostProcessor()
    {
        string str = _fileHelper.PathForTempSwf();
        StringBuilder builder = new StringBuilder(" -nativeskip -upp ");
        builder.Append(str);
        builder.Append(" -o ");
        builder.Append(str);
        builder.Append(!_settings.IsDevelopment ? " -clzma " : " -cnone ");
        builder.Append(" -inject-telemetry ");
        return StartManagedProgram(builder.ToString(), new Cil2AsOutputParser(), _fileHelper.PathForSwfPostProcessorExe());
    }

    private static bool StartManagedProgram(string arguments, UnityScriptCompilerOutputParser parser, string exe)
    {
        return StartProgramChecked(new ManagedProgram(MonoInstallationFinder.GetMonoInstallation("MonoBleedingEdge"), "4.0", exe, arguments), parser, exe);
    }

    private static bool StartProgramChecked(Program p, CompilerOutputParserBase parser, string exe)
    {
        using (p)
        {
            p.LogProcessStartInfo();
            try
            {
                p.Start();
            }
            catch
            {
                throw new System.Exception("Could not start " + exe);
            }
            p.WaitForExit();
            if (p.ExitCode == 0)
            {
                return true;
            }
            string[] errorOutput = p.GetErrorOutput();
            string[] standardOutput = p.GetStandardOutput();
            LogCompilerMessages(parser.Parse(errorOutput, standardOutput, true));
            string[] textArray1 = new string[] { exe, " Failed:", Environment.NewLine, p.GetStandardOutputAsString(), Environment.NewLine, string.Join(Environment.NewLine, errorOutput) };
            throw new System.Exception(string.Concat(textArray1));
        }
    }

    private static bool ValidateAssemblies(PostProcessFlashPlayerOptions options)
    {
        object[] objArray1 = new object[] { options };
        ValidationResult result = AssemblyValidation.Validate(RuntimePlatform.FlashPlayer, _fileHelper.GetUserAssemblies(), objArray1);
        if (result.Success)
        {
            return true;
        }
        IEnumerator<CompilerMessage> enumerator = result.CompilerMessages.GetEnumerator();
        try
        {
            while (enumerator.MoveNext())
            {
                CompilerMessage current = enumerator.Current;
                UnityEngine.Debug.LogPlayerBuildError(current.message, current.file, current.line, current.column);
            }
        }
        finally
        {
            if (enumerator == null)
            {
            }
            enumerator.Dispose();
        }
        throw new System.Exception("Validation step " + result.Rule + " Failed!");
    }

    private static void WriteHtml()
    {
        FlashTemplateWriterUtility.WriteHTMLTemplate(_settings, _fileHelper);
    }
}

